package com.ldk.admin.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ldk.framework.entity.AdminUser;
import com.ldk.framework.entity.Area;
import com.ldk.framework.entity.Oplog;
import com.ldk.framework.service.IAreaService;
import com.ldk.framework.service.IOplogService;
import net.coobird.thumbnailator.Thumbnails;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.ui.ModelMap;
import org.springframework.web.multipart.MultipartFile;

import com.ldk.admin.common.ResponseResult;
import com.ldk.admin.constants.CONFIG;
import com.ldk.admin.constants.FORM;
import com.ldk.admin.constants.LINK;
import com.ldk.admin.constants.SESSION;
import com.ldk.admin.constants.ViewMode;
import com.ldk.base.framework.util.BeanUtil;
import com.ldk.base.framework.util.ConfigUtil;
import com.ldk.base.framework.util.FileUtil;
import com.ldk.base.framework.util.PropertiesUtil;
import com.ldk.base.framework.util.SystemUtil;
import com.ldk.framework.entity.Dictdata;
import com.ldk.framework.service.IDictdataService;
import org.springframework.web.servlet.ModelAndView;

/**
 * 控制器的基类
 *
 * @author xiangwl
 * @version v1.0
 */
@Component("baseController")
public abstract class BaseController {

    @Autowired
    protected IDictdataService dictdataService;

    @Autowired
    private IOplogService oplogService;

    @Autowired
    private IAreaService areaService;

    protected BaseController() {
    }

    /**
     * 默认日志
     */
    protected Logger logger = LoggerFactory.getLogger(this.getClass());


    protected String getAdminTrueName(HttpServletRequest request) {
        Object obj = request.getSession().getAttribute(SESSION.USER);
        if (obj == null) return "";
        Map<String, Object> map = BeanUtil.toMap(obj);
        if (map == null) return "";
        return map.containsKey("trueName") ? map.get("trueName").toString() : "";
    }

    protected String getAdminUserName(HttpServletRequest request) {
        Object obj = request.getSession().getAttribute(SESSION.USER);
        if (obj == null) return "";
        Map<String, Object> map = BeanUtil.toMap(obj);
        if (map == null) return "";
        return map.containsKey("userName") ? map.get("userName").toString() : "";
    }

    protected Integer getAdminId(HttpServletRequest request) {
        Object obj = request.getSession().getAttribute(SESSION.USER);
        if (obj == null) return 0;
        Map<String, Object> map = BeanUtil.toMap(obj);
        if (map == null) return 0;
        return map.containsKey("userId") ? Integer.parseInt(map.get("userId").toString()) : 0;
    }

    protected Integer getRoleId(HttpServletRequest request) {
        Object obj = request.getSession().getAttribute(SESSION.USER);
        if (obj == null) return 0;
        Map<String, Object> map = BeanUtil.toMap(obj);
        if (map == null) return 0;
        return map.containsKey("roleId") ? Integer.parseInt(map.get("roleId").toString()) : 0;
    }

    protected Integer getAreaId(HttpServletRequest request) {
        Object obj = request.getSession().getAttribute(SESSION.USER);
        if (obj == null) return 0;
        Map<String, Object> map = BeanUtil.toMap(obj);
        if (map == null) return 0;
        return map.containsKey("areaId") ? Integer.parseInt(map.get("areaId").toString()) : 0;
    }

    protected String getAdminAreaName(HttpServletRequest request) {
        long areaId = Long.parseLong(this.getAreaId(request).toString());
        Area query = new Area();
        query.setAreaId(areaId);

        //Area model = areaService.selectByKey("", query);
        Area model = areaService.selectOne("", query);
        String areaName = "";

        if (model.getAreaId() == areaId) {
            areaName = model.getAreaName();
        }

        return areaName!=null ? areaName : "";
    }

    /**
     * 获取config.properties的文件路径
     *
     * @return
     */
    protected String getConfigPath() {
        return CONFIG.DEBUG ? this.getClass().getResource("/").getPath() + "/config_debug.properties" :
                this.getClass().getResource("/").getPath() + "/config.properties";
    }

    /**
     * 获取图片根地址
     *
     * @return
     */
    protected String getImageRoot() {
        Properties cfgProps = ConfigUtil.GetInstance().getConfig();
        String imgRoot = PropertiesUtil.getProperty(cfgProps, CONFIG.IMAGE_ROOT);
        if (!StringUtils.isEmpty(imgRoot) && !imgRoot.endsWith("/")) {
            imgRoot += "/";
        }
        return imgRoot;
    }

    /**
     * 获取图片存放的根路径
     *
     * @return
     */
    protected String getImagePath() {
        Properties cfgProps = ConfigUtil.GetInstance().getConfig();
        String imgPath = PropertiesUtil.getProperty(cfgProps, CONFIG.IMAGE_PATH);
        if (!StringUtils.isEmpty(imgPath) && !imgPath.endsWith("/")) {
            imgPath += "/";
        }
        return imgPath;
    }

    /**
     * 保存图片
     *
     * @param dir      文件保存的文件夹名称
     * @param file     图片文件
     * @param hasThumb 是否生成缩略图
     * @param hasRoot  是否包括图片访问地址根地址
     * @return
     * @throws Exception
     */
    protected Map<String, String> saveImage(String dir, MultipartFile file, Boolean hasThumb, Boolean hasRoot) throws Exception {

        if (file == null || file.isEmpty()) {
            throw new Exception("文件不能为空");
        }
        Properties cfgProps = ConfigUtil.GetInstance().getConfig();

        String imgPath = PropertiesUtil.getProperty(cfgProps, CONFIG.IMAGE_PATH);

        String folder = String.format("%s/%s", imgPath, dir);
        String orgfileName = file.getOriginalFilename();
        String ext = FileUtil.getFileExtention(orgfileName);
        String fileName = SystemUtil.generateOrderNo("") + ext;


        Boolean saved = FileUtil.saveFile(folder, fileName, file.getBytes());
        String link = "";
        String thumb = "";
        if (saved) {
            String imgRoot = PropertiesUtil.getProperty(cfgProps, CONFIG.IMAGE_ROOT);
            imgRoot = imgRoot.replace("\\", "/");
            if (!imgRoot.endsWith("/")) {
                imgRoot += "/";
            }
            if (hasRoot) {
                if (dir.startsWith("/")) {
                    dir = dir.substring(1);
                }
            }
            if (hasThumb) {
                String thumbFileName = "thumb_" + fileName;

                String filePath = folder.replace("\\", "/");
                if (!StringUtils.endsWith(filePath, "/")) {
                    filePath += "/";
                }
                String srcFile = filePath + fileName;
                String thumbFile = filePath + thumbFileName;
                Thumbnails.of(srcFile).scale(0.5f).toFile(thumbFile);
                if (hasRoot) {
                    thumb = String.format("%s%s/%s", imgRoot, dir, thumbFileName);
                } else {
                    thumb = String.format("%s/%s", dir, thumbFileName);
                }
            }

            if (hasRoot) {
                link = String.format("%s%s/%s", imgRoot, dir, fileName);
            } else {
                link = String.format("%s/%s", dir, fileName);
            }
        }
        Map<String, String> map = new HashMap<String, String>();

        map.put("link", link);
        map.put("thumb", thumb);

        return map;

    }

    /**
     * 保存文件
     *
     * @param dir        文件保存的文件夹名称
     * @param file       文件
     * @param hasRoot    是否包括文件访问地址根地址
     * @param useNewName 使用新名称
     * @return
     * @throws Exception
     */
    protected Map<String, String> saveFile(String dir, MultipartFile file, Boolean hasRoot, Boolean useNewName) throws Exception {

        if (file == null || file.isEmpty()) {
            throw new Exception("文件不能为空");
        }
        Properties cfgProps = ConfigUtil.GetInstance().getConfig();

        String imgPath = PropertiesUtil.getProperty(cfgProps, CONFIG.DOWN_FILE_PATH);

        String folder = String.format("%s/%s", imgPath, dir);
        String orgfileName = file.getOriginalFilename();
        String ext = FileUtil.getFileExtention(orgfileName);
        String fileName = useNewName ? (SystemUtil.generateOrderNo("") + ext) : orgfileName;

        Boolean saved = FileUtil.saveFile(folder, fileName, file.getBytes());
        String link = "";
        if (saved) {
            String fileRoot = PropertiesUtil.getProperty(cfgProps, CONFIG.DOWN_FILE_ROOT);
            fileRoot = fileRoot.replace("\\", "/");
            if (!fileRoot.endsWith("/")) {
                fileRoot += "/";
            }
            if (hasRoot) {
                if (dir.startsWith("/")) {
                    dir = dir.substring(1);
                }
            }

            if (hasRoot) {
                link = String.format("%s%s/%s", fileRoot, dir, fileName);
            } else {
                link = String.format("%s/%s", dir, fileName);
            }
        }
        Map<String, String> map = new HashMap<String, String>();
        map.put("link", link);

        return map;

    }


    /**
     * 设置link
     *
     * @param map        ModelMap
     * @param backText   返回文本
     * @param backUrl    返回地址
     * @param hereText   当前位置文本
     * @param hereUrl    当前位置地址
     * @param actionText 操作文本
     * @param actionHref 操作地址
     */
    protected void setLinks(ModelMap map, String backText, String backUrl, String hereText, String hereUrl, String actionText, String actionHref) {
        if (!StringUtils.isEmpty(backText) && StringUtils.trim(backText).length() > 0) {
            map.addAttribute(LINK.BACK_TEXT, backText);
        }
        if (!StringUtils.isEmpty(backUrl) && StringUtils.trim(backUrl).length() > 0) {
            if (StringUtils.startsWith(backUrl, "/")) {
                backUrl = backUrl.substring(1);
            }
            map.addAttribute(LINK.BACK_URL, backUrl);
        }
        if (!StringUtils.isEmpty(hereText) && StringUtils.trim(hereText).length() > 0) {
            map.addAttribute(LINK.HERE_TEXT, hereText);
        }
        if (!StringUtils.isEmpty(hereUrl) && StringUtils.trim(hereUrl).length() > 0) {
            if (StringUtils.startsWith(hereUrl, "/")) {
                hereUrl = hereUrl.substring(1);
            }
            map.addAttribute(LINK.HERE_URL, hereUrl);
        }
        if (!StringUtils.isEmpty(actionText) && StringUtils.trim(actionText).length() > 0) {
            map.addAttribute(LINK.ACTION_TEXT, actionText);
        }
        if (!StringUtils.isEmpty(actionHref) && StringUtils.trim(actionHref).length() > 0) {
            if (StringUtils.startsWith(actionHref, "/")) {
                actionHref = actionHref.substring(1);
            }
            map.addAttribute(LINK.ACTION_HREF, actionHref);
        }
    }

    /**
     * 设置form
     *
     * @param map        ModelMap
     * @param formAction 表单form的提交地址
     * @param rst        Result 表单操作后返回的结果
     */
    protected void setForm(ModelMap map, String formAction, ResponseResult rst) {
        if (!StringUtils.isEmpty(formAction) && StringUtils.trim(formAction).length() > 0) {
            if (StringUtils.startsWith(formAction, "/")) {
                formAction = formAction.substring(1);
            }
            map.addAttribute(FORM.FORM_ACTION, formAction);
        }
        if (rst != null) {
            map.addAttribute(FORM.FROM_RESULT, rst);
        }
        //默认添加图片访问跟地址
        map.addAttribute(FORM.IMAGE_ROOT, getImageRoot());
    }

    /**
     * 设置页面浏览模式
     *
     * @param map
     * @param mode
     */
    protected void setViewMode(ModelMap map, ViewMode mode) {
        map.addAttribute("viewMode", mode.getName());
    }

    protected List<Dictdata> getDictdataList(int dictId) {
        Dictdata query = new Dictdata();
        query.setEnabled(true);
        query.setDictId(dictId);

        return dictdataService.selectList("", query);
    }

    protected Dictdata getDictdataByName(int dictId, String dataName) {
        Dictdata query = new Dictdata();
        query.setEnabled(true);
        query.setDictId(dictId);
        query.setDataName(dataName);

        return dictdataService.selectOne("", query);
    }

    protected Dictdata getDictdataByValue(int dictId, String dataValue) {
        Dictdata query = new Dictdata();
        query.setEnabled(true);
        query.setDictId(dictId);
        query.setDataValue(dataValue);

        return dictdataService.selectOne("", query);
    }

    /**
     * 从Cell获取字符串
     *
     * @return
     */
    protected String getStringVauleFromExcel(Cell cell) {
        cell.setCellType(Cell.CELL_TYPE_STRING);
        return cell.getStringCellValue();
    }

    /**
     * 添加日志
     *
     * @param op_name: 名称
     * @param op_before: 修改前的数据
     * @param op_after: 修改后的数据
     * @param remark: 备注
     * @param operman: 操作人用户名
     * @param oper_id: 用户ID
     * @param createtime: 时间
     * @return
     */
    protected void insertOplog(HttpServletRequest request, String op_name, String op_before, String op_after, String remark, String operman,
                               Long oper_id, Long createtime) {
        Oplog opLog = new Oplog();
        opLog.setOpName(op_name);
        opLog.setOpBefore(op_before);
        opLog.setOpAfter(op_after);
        opLog.setRemark(remark);
        opLog.setOperman(this.getAdminUserName(request).toString());
        opLog.setOperId(Long.parseLong(this.getAdminId(request).toString()));
        opLog.setCreatetime(SystemUtil.getAllSeconds());
        oplogService.insert("",opLog);
    }

    /**
     * session是否过期
     */
    public void isExpired(HttpServletRequest request,HttpServletResponse response){

        //登录状态是否过期
        //if(request.getSession().getAttribute("user") == null) {
        if(request.getSession().getAttribute(SESSION.USER) == null) {
            ResponseResult rst = new ResponseResult();
            rst.AddError("登录状态已失效，请重新登录");
            try {
                response.sendRedirect("");
            } catch (Exception e) {
                //e.printStackTrace();
            }
        } else {
            //this.isForcedUpdPass(request,response);
        }
    }

    /**
     * 初次登录，强制修改密码
     */
    public void isForcedUpdPass(HttpServletRequest request,HttpServletResponse response){
        if(request.getSession().getAttribute(SESSION.USER) != null && request.getSession().getAttribute("login_count") != null) {
            AdminUser user = (AdminUser)request.getSession().getAttribute(SESSION.USER);
            long login_count = Long.parseLong(request.getSession().getAttribute("login_count").toString());
            if (login_count == 0) {
                ResponseResult rst = new ResponseResult();
                rst.AddError("必须修改初始密码才能使用本系统！");
                try {
                    new ModelAndView(request.getContextPath()+"/admin/userPassowd/"+user.getUserId());
                    //response.sendRedirect(request.getContextPath()+"/admin/userPassowd/"+user.getUserId());
                } catch (Exception e) {
                    //e.printStackTrace();
                }
            }
        }
    }
}
